Análisis de las votaciones de la Cámara de Diputadas y Diputados¶

Introducción¶

En el presente notebook se analizarán las votaciones realizadas por la Cámara de Diputadas y Diputados de Chile en su LVI periodo legislativo (iniciado el 11 de marzo de 2022). La metodología fue inspirada en FiveThirtyEight, quienes realizaron un análisis similar para la Cámara de Representantes de los Estados Unidos.

Los datos fueron obtenidos mediante Datos Abiertos Legislativos, debiéndose procesar los XML con el detalle de cada votación entre el 11 de marzo de 2022 y la fecha de realización del análisis (13 de octubre de 2024). La militancia actual de cada diputado también fue extraída de la plataforma. A cada diputado se le asoció un número por cada votación realizada en el Congreso: 1 si el diputado aprobó la moción, -1 si la rechazó, y 0 si se abstuvo. Los valores faltantes (debido a ausencias de los diputados) se calcularon usando imputación mediante KNN.

Luego, se realizó Principal Component Analysis (PCA) sobre la tabla resultante, para asociar a cada diputado con una coordenada en 2 dimensiones que refleja sus patrones de voto. Se encontró una clara asociación entre la primera coordenada del PCA y la posición del diputado en el clásico eje izquierda-derecha. Usando estos valores, se analizaron las tendencias de los diputados y sus partidos políticos, incluyendo la cohesión de estos últimos a la hora de votar.

Finalmente, se realizó un clustering utilizando K-Means con $k=5$, obteniendo 5 grupos de diputados que votan de manera similar. Cada grupo fue posteriormente analizado, concluyendo que los clusters calzan con las principales fuerzas políticas visibles al interior del Congreso.

In [1]:
import xml.etree.ElementTree as ET
import requests

import pickle
import pandas as pd
import numpy as np
from datetime import datetime

import matplotlib.pyplot as plt
import plotly.express as px

from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.impute import KNNImputer

from plotly.offline import init_notebook_mode
init_notebook_mode()

Carga de datos¶

In [212]:
# fechas para las cuales se tomará información
start_date = datetime.strptime("2022-03-11", "%Y-%m-%d")
end_date = datetime.strptime("2024-10-13", "%Y-%m-%d")

# prefijo para los sitios de las requests
vote_req_prefix = "https://opendata.camara.cl/camaradiputados/WServices/WSLegislativo.asmx/"
deputy_req_prefix = "https://opendata.camara.cl/camaradiputados/WServices/WSDiputado.asmx/"

# prefijo para las tags de los archivos XML
tag_prefix = r"{http://opendata.camara.cl/camaradiputados/v1}"


# función auxiliar para parsear fechas
def parse_date(date_str):
   return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%S") 

Para cada año de nuestro interés, se obtienen todas las votaciones de ese año. Para cada votación, buscamos y guardamos la opción por la cual votó cada uno de los diputados (1 si fue a favor, -1 si fue en contra, 0 si se abstuvo, e inicialmente NaN si no estaba presente).

In [66]:
votes_dict = {}  # diccionario con todas las votaciones

# en orden inverso (porque así está ordenado el XML)
years = range(end_date.year, start_date.year-1, -1)

for year in years:

    # obtenemos lista de votaciones de ese año
    votings_request = requests.get(
        vote_req_prefix + "retornarVotacionesXAnno",
        params={"prmAnno": year}
    )
    votings = ET.fromstring(votings_request.content)

    for voting in votings:
        
        # revisa si la votación está dentro de los límites, la salta si no
        voting_date = parse_date(voting.find(tag_prefix + "Fecha").text)
        if voting_date < start_date or voting_date > end_date:
            continue
        
        voting_id = voting[0].text  # id de la votación
        votes_dict[voting_id] = {}  # dict de la votación actual
        print(f"Procesando votación {voting_id}", end="\r")
        
        # obtenemos detalles de la votación
        voting_detail_request = requests.get(
            vote_req_prefix + "retornarVotacionDetalle",
            params={"prmVotacionId": voting_id}
        )
        voting_detail = ET.fromstring(voting_detail_request.content)
        
        # votos individuales en la votación
        votes = voting_detail.find(tag_prefix + "Votos")
        
        for vote in votes:
            
            deputy_id = vote[0][0].text  # id del diputado
            deputy_choice = vote[1].attrib["Valor"]  # opción por la cual votó
            
            # se agrega al diccionario
            votes_dict[voting_id][deputy_id] = deputy_choice
Procesando votación 38467
In [151]:
vote_df = pd.DataFrame(votes_dict)
vote_df = vote_df.astype(float)
vote_df = vote_df.replace(to_replace={0: -1, 2: 0})

vote_df
Out[151]:
43918 43917 43914 43913 43912 43911 43907 43906 43905 43904 ... 38482 38481 38478 38477 38476 38475 38474 38469 38468 38467
1171 -1.0 NaN -1.0 -1.0 1.0 1.0 NaN NaN NaN NaN ... -1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
1121 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1139 1.0 NaN 1.0 1.0 NaN NaN 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
1105 -1.0 1.0 -1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 ... 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
976 1.0 1.0 1.0 1.0 -1.0 NaN 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1113 NaN NaN 1.0 1.0 -1.0 NaN 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
989 NaN NaN NaN 1.0 -1.0 NaN 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1158 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1116 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
1154 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN 1.0 1.0 1.0

155 rows × 3980 columns

Ahora, a cada valor nulo le asignamos el promedio de sus 10 vecinos más cercanos, para no tener que asignarle un valor arbitrario a las ausencias. Esto se realiza mediante KNNImputer.

In [152]:
imputer = KNNImputer(n_neighbors=10)
imputer.set_output(transform="pandas")
vote_df = imputer.fit_transform(vote_df)

vote_df
Out[152]:
43918 43917 43914 43913 43912 43911 43907 43906 43905 43904 ... 38482 38481 38478 38477 38476 38475 38474 38469 38468 38467
1171 -1.0 -1.0 -1.0 -1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... -1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
1121 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1139 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0
1105 -1.0 1.0 -1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 ... 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
976 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1113 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
989 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1158 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1116 -0.8 0.6 0.3 0.7 -0.3 1.0 1.0 1.0 1.0 1.0 ... -0.6 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -1.0 -1.0
1154 1.0 1.0 1.0 1.0 -1.0 0.1 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 0.9 -1.0 1.0 1.0 1.0

155 rows × 3978 columns

Finalmente, se procesan los diputados con su información relevante, y se agregan al final de la tabla con los resultados de las votaciones.

In [123]:
deputy_indices = []
deputy_data = []

deputies_request = requests.get(deputy_req_prefix + "retornarDiputados")
deputies = ET.fromstring(deputies_request.content)

for deputy in deputies:
    
    deputy_id = deputy.find(tag_prefix + "Id").text
    
    # caso borde
    if deputy_id == "9999":
        continue
    
    deputy_first_name = deputy.find(tag_prefix + "Nombre").text
    deputy_last_name = deputy.find(tag_prefix + "ApellidoPaterno").text
    deputy_sex = deputy.find(tag_prefix + "Sexo").text

    # último partido al cual ha pertenecido el diputado
    militancies = deputy.find(tag_prefix + "Militancias")
    last_militancy_start = None
    deputy_party = None
    for militancy in militancies:
        
        militancy_start = parse_date(militancy[1].text)
        if (
            last_militancy_start is None
            or militancy_start > last_militancy_start
        ):
            last_militancy_start = militancy_start
            deputy_party = militancy[2][1].text
    
    deputy_indices.append(deputy_id)
    deputy_data.append([
        deputy_first_name,
        deputy_last_name,
        deputy_sex,
        deputy_party
    ])

deputy_df = pd.DataFrame(
    index=deputy_indices,
    columns=["nombre", "apellido", "sexo", "partido"],
    data=deputy_data
)
deputy_df
    
Out[123]:
nombre apellido sexo partido
208 Víctor Pérez Masculino Unión Demócrata Independiente
485 Jorge Pizarro Masculino Partido Demócrata Cristiano
684 Sergio Pizarro Masculino Partido Demócrata Cristiano
696 José Alfonso Rodríguez Masculino Renovación Nacional
951 David Sandoval Masculino Unión Demócrata Independiente
... ... ... ... ...
1106 Miguel Ángel Becker Masculino Renovación Nacional
1118 Ricardo Cifuentes Masculino Partido Demócrata Cristiano
1135 Johannes Kaiser Masculino Independientes
1144 Christian Matheson Masculino Independientes
1149 Carla Morales Femenino Renovación Nacional

551 rows × 4 columns

In [153]:
# juntamos los resultados de las votaciones con la info. de los diputados
vote_df = vote_df.merge(
    right=deputy_df,
    how="left",
    left_index=True,
    right_index=True
)

vote_df
Out[153]:
43918 43917 43914 43913 43912 43911 43907 43906 43905 43904 ... 38476 38475 38474 38469 38468 38467 nombre apellido sexo partido
1171 -1.0 -1.0 -1.0 -1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 -1.0 -1.0 Emilia Schneider Femenino Frente Amplio
1121 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 Eduardo Cornejo Masculino Unión Demócrata Independiente
1139 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 Enrique Lee Masculino Independientes
1105 -1.0 1.0 -1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 -1.0 -1.0 Héctor Barría Masculino Partido Demócrata Cristiano
976 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 -1.0 1.0 1.0 1.0 Juan Antonio Coloma Masculino Unión Demócrata Independiente
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1113 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 Marta Bravo Femenino Unión Demócrata Independiente
989 1.0 1.0 1.0 1.0 -1.0 0.9 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 Joaquín Lavín Masculino Unión Demócrata Independiente
1158 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 Víctor Alejandro Pino Masculino Partido Demócratas Chile
1116 -0.8 0.6 0.3 0.7 -0.3 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 -1.0 -1.0 Felipe Camaño Masculino Independientes
1154 1.0 1.0 1.0 1.0 -1.0 0.1 1.0 1.0 1.0 1.0 ... 1.0 0.9 -1.0 1.0 1.0 1.0 Mauricio Ojeda Masculino Independientes

155 rows × 3982 columns

In [253]:
# guardado de datos (para no tener que ejecutar la carga de nuevo)
vote_df.to_pickle("data/vote_df.pkl")

PCA (Principal Component Analysis)¶

In [2]:
# cargado de datos
with open("data/vote_df.pkl", 'rb') as file:
    vote_df = pickle.load(file)

Realizamos Principal Component Analysis para reducir el espacio de trabajo a solo 2 dimensiones y así poder visualizarlo.

Si etiquetamos cada diputado según el partido al cual pertenece, se puede observar claramente que la primera componente del PCA corresponde a un eje político izquierda-derecha. La segunda componente no tiene una explicación tan clara, pero solo explica un 7% de la varianza (versus el 64% que explica la primera componente), por lo cual su análisis probablemente requiera una comprensión más profunda sobre las relaciones al interior del Congreso.

En cuanto a la ubicación de cada uno de los diputados, se presentan algunas observaciones interesantes:

  • Aunque pertenece al Partido Comunista, la diputada Cariola tiene patrones de votación mucho más similares a aquellos del Frente Amplio.
  • El diputado Pino, aunque actualmente pertenece a Demócratas, tiene un historial de votación mucho más cercano al bloque de Chile Vamos.
  • Los políticos más "de izquierda" pertenecen al Partido Comunista y a Acción Humanista, mientras que los más "de derecha" son militantes o están asociados al Partido Republicano.
  • Existe un alto nivel de polarización en el Congreso, con una cantidad muy pequeña de diputados ubicados en el "centro" político. Solo 16 de los 155 diputados (10%) tienen una primera componente entre -20 y 20, aunque este rango considere un 47% del espacio entre los diputados más extremos.
  • Todos los partidos políticos con más de un par de diputados parecen estar bastante cohesionados en "bloques" definidos.

En relación a este último punto, podemos calcular cuánta "separación" hay al interior de cada partido, mediante la distancia promedio de los diputados al centroide del partido al cual pertenecen. Claramente la mayor separación corresponde a los políticos independientes, pero se puede observar que entre los partidos con alta separación se encuentran Demócratas (por el diputado Pino), la DC (probablemente debido al diputado Aedo) y la UDI (que tiene un espectro bastante amplio en la segunda componente del PCA, con algunos diputados que se asemejan a RN/Evópoli y otros que se acercan más al cluster Republicano). Por el contrario, los partidos con mayor cohesión (que tengan más de un diputado) son Acción Humanista, el Partido Comunista y Republicanos.

In [3]:
# dataframe solo con valores numéricos
vote_df_num = vote_df.iloc[:, :-4]

# hacemos PCA
pca = PCA(n_components=2)
pca_fit = pca.fit_transform(vote_df_num)
pca_df = pd.DataFrame(pca_fit, columns=['PCA1', 'PCA2'])

# agregamos columna de partido, nombre y apellido para plottear
pca_df[["nombre", "apellido", "partido"]] = (
    vote_df[["nombre", "apellido", "partido"]]
    .reset_index(drop=True)
)

print("Porcentaje de la varianza explicada por cada componente:")
print(pca.explained_variance_ratio_)
Porcentaje de la varianza explicada por cada componente:
[0.64127907 0.07304191]
In [4]:
# código auxiliar para asignar un color (arbitrario) a cada partido político
color_sequence = px.colors.qualitative.Light24
parties = pca_df["partido"].drop_duplicates().sort_values()
color_map = dict(zip(parties, color_sequence))
In [5]:
# plot con la distribución de los diputados en 2 dimensiones

fig = px.scatter(
    pca_df,
    x="PCA1",
    y="PCA2",
    color="partido",
    hover_data=["nombre", "apellido"],
    color_discrete_map=color_map,
    title="Distribución de diputados según PCA"
)
fig.update_layout(
    autosize=False,
    width=1000,
    height=600,
)
fig.show()
In [71]:
# ordenamos los diputados según PCA1 y les asignamos su posición en `index`
pca_df_ordered = (
    pca_df.sort_values("PCA1")
    .reset_index()[["PCA1", "partido", "nombre", "apellido"]]
    .reset_index()
)
fig = px.scatter(
    pca_df_ordered,
    x="PCA1",
    y="index",
    color="partido",
    hover_data=["nombre", "apellido"],
    color_discrete_map=color_map,
    title="Diputados según eje izquierda-derecha (componente 1 de PCA)",
)
fig.update_layout(
    autosize=False,
    width=1000,
    height=1000,
)
fig.show()
In [9]:
# diputados más "extremos"
(pca_df.sort_values("PCA1").reset_index())[
    ["PCA1", "partido", "nombre", "apellido"]
]
Out[9]:
PCA1 partido nombre apellido
0 -41.784536 Partido Comunista Lorena Pizarro
1 -41.734838 Partido Comunista Matías Ramírez
2 -41.694687 Partido Comunista Nathalie Castillo
3 -41.591144 Partido Acción Humanista Tomás Hirsch
4 -41.533545 Partido Comunista María Candelaria Acevedo
... ... ... ... ...
150 42.971491 Partido Republicano Luis Sánchez
151 42.986982 Partido Republicano Juan Irarrázaval
152 43.005649 Partido Republicano Benjamín Moreno
153 43.028973 Partido Republicano Agustín Romero
154 43.086088 Independientes Harry Jürgensen

155 rows × 4 columns

In [6]:
# posición promedio de cada partido
party_means = (
    pca_df.groupby("partido", sort=False)[["PCA1", "PCA2"]]
    .mean()
    .reset_index()
)
fig = px.scatter(
    party_means,
    x="PCA1",
    y="PCA2",
    color="partido",
    color_discrete_map=color_map,
    title="Posición promedio de los diputados de cada partido"
)
fig.update_layout(
    autosize=False,
    width=1000,
    height=600,
)
fig.show()
In [11]:
# función para calcular la distancia promedio de los diputados a la media
# de su partido (una forma de ver la dispersión en sus decisiones)
def distance_to_mean(df):
    
    return np.sqrt((np.square(df - df.mean())).sum(axis=1)).mean()

party_distances = (
    vote_df
    .drop(columns=["nombre", "apellido", "sexo"])
    .groupby("partido", sort=False)
    .apply(distance_to_mean)
)
party_distances = (
    party_distances
    .to_frame()
    .reset_index()
    .rename(columns={0: "avg_dist_to_mean"})
    .sort_values(by="avg_dist_to_mean", ascending=False)
)

party_distances
Out[11]:
partido avg_dist_to_mean
2 Independientes 41.997666
12 Partido Demócratas Chile 23.482063
3 Partido Demócrata Cristiano 20.039613
1 Unión Demócrata Independiente 18.893923
11 Partido Social Cristiano 17.841666
6 Partido Socialista 17.263220
8 Renovación Nacional 16.768582
9 Partido Por la Democracia 14.989334
0 Frente Amplio 13.829228
13 Partido Liberal de Chile 13.297805
16 Evolución Política 11.994269
17 Partido Radical de Chile 10.842278
5 Partido Republicano 9.400141
10 Partido Comunista 9.317484
7 Partido Acción Humanista 7.753870
4 Partido Humanista 0.000000
14 Federación Regionalista Verde Social 0.000000
15 Movimiento Amarillos por Chile 0.000000

Clustering¶

Se utilizó K-Means para el clustering, decidiéndose utilizar 5 clusters tras la realización del método del codo.

In [12]:
sse = []
clusters = list(range(1, 16))
for k in clusters:
    kmeans = KMeans(n_clusters=k, n_init=10, random_state=0).fit(vote_df_num)
    sse.append(kmeans.inertia_)

plt.plot(clusters, sse, marker="o")
plt.title("Método del codo")
plt.xlabel("Número de clusters")
plt.ylabel("SSE")
plt.grid(True)
plt.show()
No description has been provided for this image
In [69]:
# k-means con 5 clusters
kmeans5 = KMeans(n_clusters=5, n_init=100, random_state=0).fit(vote_df_num)
cluster_labels = kmeans5.labels_ + 1

fig = px.scatter(
    pca_df,
    x="PCA1",
    y="PCA2",
    color=cluster_labels.astype(str),
    hover_data=["partido", "nombre", "apellido"],
    color_discrete_sequence=px.colors.qualitative.T10,
    title="K-Means, 5 clusters",
    category_orders={"color": ["1", "2", "3", "4", "5"]},
    labels={"color": "cluster"}
)
fig.update_layout(
    autosize=False,
    width=1000,
    height=600,
)
fig.show()

Análisis de clusters¶

In [58]:
# función auxiliar que retorna un dataframe con todos los diputados que
# pertenecen a un cluster en particular, ordenados por partido y nombre
def list_cluster_deputies(
    cluster_idx,
    cluster_labels=cluster_labels,
    df=vote_df
):
    cluster_deps = df.loc[cluster_labels == cluster_idx]
    cluster_deps = cluster_deps.sort_values(["partido", "apellido", "nombre"])
    return cluster_deps[["nombre", "apellido", "sexo", "partido"]]


# función auxiliar que recibe un índice de cluster, y retorna un dataframe
# donde a cada partido se le asocia el porcentaje de sus diputados que
# pertenecen a dicho cluster
def percentage_of_parties_in_cluster(
    cluster_idx,
    cluster_labels=cluster_labels,
    df=vote_df
):
    
    all_parties = df["partido"].value_counts()
    
    cluster_parties = (
        df.loc[cluster_labels == cluster_idx]["partido"]
        .value_counts()
    )
    
    parties_comp = pd.merge(
        left=all_parties,
        right=cluster_parties,
        how="right",
        left_index=True,
        right_index=True,
        suffixes=("_all", "_cluster")
    )
    parties_comp["porcentaje"] = (
        parties_comp["count_cluster"]
        / parties_comp["count_all"]
    )
    
    return (
        parties_comp["porcentaje"]
        .sort_values(ascending=False)
        .to_frame()
        .reset_index()
        .rename(columns={0: "porcentaje"})
    )

Cluster 1: Demócratas/ex-PDG¶

El primer cluster está compuesto por 10 diputados:

  • 6 diputados independientes (14% del total de independientes). 3 de ellos (Medina, Oyarzo y Rivas) fueron electos por el Partido de la Gente, pero posteriormente abandonaron el partido. El diputado Pulgar fue electo en cupo de Centro Unido pero inmediatamente pasó a formar parte de la bancada del PDG.
  • 3 diputados de Demócratas (75% de los diputados del partido). El diputado Pino pertenece a Demócratas, pero fue asignado al cluster 3.
  • Un diputado de Amarillos (100% de los diputados del partido).
In [59]:
list_cluster_deputies(1)
Out[59]:
nombre apellido sexo partido
1016 Miguel Ángel Calisto Masculino Independientes
1116 Felipe Camaño Masculino Independientes
1145 Karen Medina Femenino Independientes
1155 Rubén Darío Oyarzo Masculino Independientes
1161 Francisco Pulgar Masculino Independientes
948 Gaspar Rivas Masculino Independientes
1134 Andrés Jouannet Masculino Movimiento Amarillos por Chile
1057 Erika Olivera Femenino Partido Demócratas Chile
1062 Joanna Pérez Femenino Partido Demócratas Chile
1168 Jorge Saffirio Masculino Partido Demócratas Chile
In [60]:
percentage_of_parties_in_cluster(1)
Out[60]:
partido porcentaje
0 Movimiento Amarillos por Chile 1.000000
1 Partido Demócratas Chile 0.750000
2 Independientes 0.142857

Cluster 2: Socialismo Democrático¶

El segundo cluster está compuesto por 37 diputados, pertenencientes en su gran mayoría al Socialismo Democrático:

  • 12 diputados independientes (29% del total de independientes). La mayoría fueron electos como independientes en cupos del Socialismo Democrático.
  • 12 diputados del Partido Socialista (100% de los diputados del partido).
  • 4 diputados de la Democracia Cristiana (100% de los diputados del partido).
  • 3 diputados del Partido Liberal (100% de los diputados del partido).
  • 3 diputados del PPD (100% de los diputados del partido).
  • 2 diputados del Partido Radical (100% de los diputados del partido).
  • Una diputada del Partido Humanista (100% de los diputados del partido).
In [61]:
list_cluster_deputies(2)
Out[61]:
nombre apellido sexo partido
803 René Alinco Masculino Independientes
1099 Jaime Araya Masculino Independientes
1101 Mónica Arce Femenino Independientes
1110 Carlos Bianchi Masculino Independientes
1124 Tomás De Rementería Masculino Independientes
1125 Viviana Delgado Femenino Independientes
1130 Marta González Femenino Independientes
1137 Tomás Lagomarsino Masculino Independientes
1151 Camila Musante Femenino Independientes
1175 Cristián Tapia Masculino Independientes
1178 Héctor Ulloa Masculino Independientes
1182 Sebastián Videla Masculino Independientes
1097 Eric Aedo Masculino Partido Demócrata Cristiano
1105 Héctor Barría Masculino Partido Demócrata Cristiano
1118 Ricardo Cifuentes Masculino Partido Demócrata Cristiano
1179 Alberto Undurraga Masculino Partido Demócrata Cristiano
1039 Pamela Jiles Femenino Partido Humanista
1013 Alejandro Bernales Masculino Partido Liberal de Chile
1141 Luis Malla Masculino Partido Liberal de Chile
991 Vlado Mirosevic Masculino Partido Liberal de Chile
1048 Carolina Marzán Femenino Partido Por la Democracia
1147 Helia Molina Femenino Partido Por la Democracia
1077 Raúl Soto Masculino Partido Por la Democracia
1049 Cosme Mellado Masculino Partido Radical de Chile
1076 Alexis Sepúlveda Masculino Partido Radical de Chile
1103 Danisa Astudillo Femenino Partido Socialista
1112 Ana María Bravo Femenino Partido Socialista
975 Daniella Cicardini Femenino Partido Socialista
1038 Marcos Ilabaca Masculino Partido Socialista
1044 Raúl Leiva Masculino Partido Socialista
1142 Daniel Manouchehri Masculino Partido Socialista
990 Daniel Melo Masculino Partido Socialista
74 Jaime Naranjo Masculino Partido Socialista
1056 Emilia Nuyado Femenino Partido Socialista
1073 Juan Santana Masculino Partido Socialista
1002 Leonardo Soto Masculino Partido Socialista
1181 Nelson Venegas Masculino Partido Socialista
In [62]:
percentage_of_parties_in_cluster(2)
Out[62]:
partido porcentaje
0 Partido Socialista 1.000000
1 Partido Demócrata Cristiano 1.000000
2 Partido Por la Democracia 1.000000
3 Partido Liberal de Chile 1.000000
4 Partido Radical de Chile 1.000000
5 Partido Humanista 1.000000
6 Independientes 0.285714

Cluster 3: Chile Vamos¶

El tercer cluster es el más grande, y está compuesto por 55 diputados, pertenencientes en su gran mayoría a Chile Vamos:

  • 20 diputados de la UDI (100% de los diputados del partido).
  • 17 diputados de Renovación Nacional (100% de los diputados del partido).
  • 12 diputados independientes (29% del total de independientes). La mayoría fueron electos como independientes en cupos de Chile Vamos.
  • 3 diputados del Partido Social Cristiano (100% de los diputados del partido).
  • 2 diputados de Evópoli (100% de los diputados del partido).
  • Un diputado de Demócratas (25% de los diputados del partido). Corresponde al diputado Pino antes mencionado.
In [63]:
list_cluster_deputies(3)
Out[63]:
nombre apellido sexo partido
1132 Jorge Guzmán Masculino Evolución Política
1081 Francisco Undurraga Masculino Evolución Política
1098 Yovana Ahumada Femenino Independientes
971 Bernardo Berger Masculino Independientes
1022 Sofía Cid Femenino Independientes
1120 María Luisa Cordero Femenino Independientes
1025 Catalina Del Real Femenino Independientes
1136 Paula Labra Femenino Independientes
1139 Enrique Lee Masculino Independientes
1144 Christian Matheson Masculino Independientes
1157 Marlene Pérez Femenino Independientes
1166 Natalia Romero Femenino Independientes
1176 Hotuiti Teao Masculino Independientes
1003 Renzo Trisotti Masculino Independientes
1158 Víctor Alejandro Pino Masculino Partido Demócratas Chile
1102 Roberto Arroyo Masculino Partido Social Cristiano
1119 Sara Concha Femenino Partido Social Cristiano
1054 Francesca Muñoz Femenino Partido Social Cristiano
1106 Miguel Ángel Becker Masculino Renovación Nacional
1108 Juan Carlos Beltrán Masculino Renovación Nacional
1019 José Miguel Castro Masculino Renovación Nacional
1021 Andrés Celis Masculino Renovación Nacional
1028 Eduardo Durán Masculino Renovación Nacional
1027 Jorge Durán Masculino Renovación Nacional
1030 Camila Flores Femenino Renovación Nacional
1131 Mauro González Masculino Renovación Nacional
1046 Andrés Longton Masculino Renovación Nacional
1050 Miguel Mellado Masculino Renovación Nacional
1149 Carla Morales Femenino Renovación Nacional
1059 Ximena Ossandón Femenino Renovación Nacional
1163 Marcia Raphael Femenino Renovación Nacional
999 Jorge Rathgeb Masculino Renovación Nacional
1067 Hugo Rey Masculino Renovación Nacional
953 Frank Sauerbaum Masculino Renovación Nacional
1075 Diego Schalper Masculino Renovación Nacional
1009 Jorge Alessandri Masculino Unión Demócrata Independiente
1109 Gustavo Benavente Masculino Unión Demócrata Independiente
815 Sergio Bobadilla Masculino Unión Demócrata Independiente
1113 Marta Bravo Femenino Unión Demócrata Independiente
1111 Fernando Bórquez Masculino Unión Demócrata Independiente
1017 Álvaro Carter Masculino Unión Demócrata Independiente
976 Juan Antonio Coloma Masculino Unión Demócrata Independiente
1121 Eduardo Cornejo Masculino Unión Demócrata Independiente
1126 Felipe Donoso Masculino Unión Demócrata Independiente
1031 Juan Fuenzalida Masculino Unión Demócrata Independiente
1094 Cristian Labbé Masculino Unión Demócrata Independiente
989 Joaquín Lavín Masculino Unión Demócrata Independiente
1138 Henry Leal Masculino Unión Demócrata Independiente
1140 Daniel Lilayu Masculino Unión Demócrata Independiente
1143 Cristóbal Martínez Masculino Unión Demócrata Independiente
1053 Cristhian Moreira Masculino Unión Demócrata Independiente
1065 Guillermo Ramírez Masculino Unión Demócrata Independiente
1174 Marco Antonio Sulantay Masculino Unión Demócrata Independiente
917 Gastón Von Mühlenbrock Masculino Unión Demócrata Independiente
1183 Flor Weisse Femenino Unión Demócrata Independiente
In [64]:
percentage_of_parties_in_cluster(3)
Out[64]:
partido porcentaje
0 Unión Demócrata Independiente 1.000000
1 Renovación Nacional 1.000000
2 Partido Social Cristiano 1.000000
3 Evolución Política 1.000000
4 Independientes 0.285714
5 Partido Demócratas Chile 0.250000

Cluster 4: Frente Amplio/Chile Digno¶

El cuarto cluster está compuesto por 38 diputados, pertenencientes en su gran mayoría al Frente Amplio y Chile Digno:

  • 20 diputados del Frente Amplio (100% de los diputados del partido)
  • 10 diputados del Partido Comunista (100% de los diputados del partido)
  • 5 diputados independientes (12% del total de independientes).
  • 2 diputados de Acción Humanista (100% de los diputados del partido).
  • Un diputado del FREVS (100% de los diputados del partido).
In [65]:
list_cluster_deputies(4)
Out[65]:
nombre apellido sexo partido
872 Jaime Mulet Masculino Federación Regionalista Verde Social
1107 María Francisca Bello Femenino Frente Amplio
1015 Jorge Brito Masculino Frente Amplio
1114 Félix Bugueño Masculino Frente Amplio
1127 Lorena Fries Femenino Frente Amplio
1129 Andrés Giordano Masculino Frente Amplio
1037 Diego Ibáñez Masculino Frente Amplio
1051 Claudia Mix Femenino Frente Amplio
1148 Javiera Morales Femenino Frente Amplio
1058 Maite Orsini Femenino Frente Amplio
1063 Catalina Pérez Femenino Frente Amplio
1164 Marcela Riquelme Femenino Frente Amplio
1068 Camila Rojas Femenino Frente Amplio
1070 Patricio Rosas Masculino Frente Amplio
1169 Clara Sagardia Femenino Frente Amplio
1171 Emilia Schneider Femenino Frente Amplio
1167 Jaime Sáez Masculino Frente Amplio
1177 Carolina Tello Femenino Frente Amplio
1086 Gonzalo Winter Masculino Frente Amplio
1087 Gael Yeomans Femenino Frente Amplio
1153 Ericka Ñanco Femenino Frente Amplio
1115 Mercedes Bulnes Femenino Independientes
1034 Félix González Masculino Independientes
1156 Hernán Palma Masculino Independientes
1074 Marisela Santibáñez Femenino Independientes
1180 Consuelo Veloso Femenino Independientes
1128 Ana María Gazmuri Femenino Partido Acción Humanista
1036 Tomás Hirsch Masculino Partido Acción Humanista
1096 María Candelaria Acevedo Femenino Partido Comunista
1012 Boris Barrera Masculino Partido Comunista
973 Karol Cariola Femenino Partido Comunista
1117 Nathalie Castillo Femenino Partido Comunista
1122 Luis Alberto Cuello Masculino Partido Comunista
1035 Carmen Hertz Femenino Partido Comunista
1159 Lorena Pizarro Femenino Partido Comunista
1160 Alejandra Placencia Femenino Partido Comunista
1162 Matías Ramírez Masculino Partido Comunista
1173 Daniela Serrano Femenino Partido Comunista
In [66]:
percentage_of_parties_in_cluster(4)
Out[66]:
partido porcentaje
0 Frente Amplio 1.000000
1 Partido Comunista 1.000000
2 Partido Acción Humanista 1.000000
3 Federación Regionalista Verde Social 1.000000
4 Independientes 0.119048

Cluster 5: Republicanos¶

El quinto y último cluster está compuesto por 15 diputados:

  • 8 diputados del Partido Republicano (100% de los diputados del partido)
  • 7 diputados independientes (17% del total de independientes). Todos están asociados al Partido Republicano (fueron electos como independientes en cupos de Republicanos, o fueron electos mientras pertenecían al partido y luego fueron expulsados o renunciaron).
In [67]:
list_cluster_deputies(5)
Out[67]:
nombre apellido sexo partido
1123 Gonzalo De la Carrera Masculino Independientes
1040 Harry Jürgensen Masculino Independientes
1135 Johannes Kaiser Masculino Independientes
1152 Gloria Naveillan Femenino Independientes
1154 Mauricio Ojeda Masculino Independientes
1069 Leonidas Romero Masculino Independientes
1172 Stephan Schubert Masculino Independientes
1100 Cristián Araya Masculino Partido Republicano
1104 Chiara Barchiesi Femenino Partido Republicano
1133 Juan Irarrázaval Masculino Partido Republicano
1146 José Carlos Meza Masculino Partido Republicano
1150 Benjamín Moreno Masculino Partido Republicano
1165 Agustín Romero Masculino Partido Republicano
1170 Luis Sánchez Masculino Partido Republicano
1082 Cristóbal Urruticoechea Masculino Partido Republicano
In [68]:
percentage_of_parties_in_cluster(5)
Out[68]:
partido porcentaje
0 Partido Republicano 1.000000
1 Independientes 0.166667